package productions;

import exceptions.ParserException;
import lexico.ErrorTable;
import lexico.SymbolTable;
import lexico.TokenClass;

/**
 * @author heekinho
 */
public class TipoDefinidoProduction extends AbstractProductionRule {
    /* Muitos dos métodos irão precisar de algo assim: */

    private static TipoDefinidoProduction instance = new TipoDefinidoProduction();

    public static TipoDefinidoProduction getInstance() {
        return instance;
    }

    /**
     * Regra: 'tipo' (registro | tipo_primitivo) IDENTIFIER ';'
     * @return
     * @throws ParserException
     */
    @Override
    public boolean analyze(SymbolTable st, ErrorTable et) throws ParserException {
        if (!basicParse(st, TokenClass.KEYWORD_TIPO)) {
            return false;
        }

        if (!(TipoPrimitivoProduction.getInstance().analyze(st, et)
                || RegistroProduction.getInstance().analyze(st, et))) {
            return skipUntilSynchronize(st, et, "Era esperado um tipo ou 'registro'");
        }

        if (!basicParse(st, TokenClass.IDENTIFIER)) {
            return skipUntilSynchronize(st, et, "Era esperado um identificador");
        }
        if (!basicParse(st, TokenClass.DELIMITER_SEMICOLON)) {
            return skipUntilSynchronize(st, et, "Era esperado um ';'");
        }

        return true;
    }

    @Override
    protected void populateFirst() {
        first.add(TokenClass.KEYWORD_TIPO);
    }

    @Override
    protected void populateFollow() {

        //from declarations.follow
        follow.add(TokenClass.KEYWORD_FUNCAO);

        //from variaveis.first
        follow.add(TokenClass.KEYWORD_VARIAVEIS);

        //from constantes.first
        follow.add(TokenClass.KEYWORD_CONSTANTES);
    }

}
